package com.ndood.admin.core.security;

import java.util.List;
import java.util.Map;
import java.util.Optional;

import javax.transaction.Transactional;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.social.security.SocialUserDetails;
import org.springframework.social.security.SocialUserDetailsService;
import org.springframework.stereotype.Component;

import com.google.common.collect.Maps;
import com.ndood.admin.pojo.system.PermPo;
import com.ndood.admin.pojo.system.RolePo;
import com.ndood.admin.pojo.system.StaffPo;
import com.ndood.admin.pojo.system.dto.StaffDto;
import com.ndood.admin.repository.system.StaffRepository;
import com.ndood.common.base.util.JPAUtil;
import com.ndood.common.base.util.RegexUtils;

/**
 * 自定义UserDetailsService
 * @author ndood
 */
@Transactional
@Component
public class AdminUserDetailsService implements UserDetailsService, SocialUserDetailsService {

	private Logger logger = LoggerFactory.getLogger(getClass());

	@Autowired
	private StaffRepository userRepository;

	/**
	 * 根据username获取用户信息
	 */
	@Override
	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
		
		logger.debug("Step1: 进行登录，表单登录用户名:" + username);

		StaffPo user = null;
		if (RegexUtils.checkEmail(username)) {
			
			// 查看是否存在未激活邮箱
			user = userRepository.findByEmailAndStatus(username,1);
			if(user!=null) {
				throw new UsernameNotFoundException("用户不存在，或已冻结!");
			}

		} else if (RegexUtils.checkMobile(username)) {
			user = userRepository.findByMobileAndStatus(username,1);
			
		} else {
			
			try {
				Integer.parseInt(username);
			} catch (Exception e) {
				throw new UsernameNotFoundException("无效的账户名!");
			}
			
			// 适用于rememeberMe的调用
			Optional<StaffPo> option = userRepository.findById(Integer.parseInt(username));
			if(!option.isPresent()) {
				throw new UsernameNotFoundException("用户不存在，或已冻结!");
			}
			user = option.get();
		}

		if (user == null) {
			throw new UsernameNotFoundException("用户不存在，或已冻结!");
		}

		logger.debug("Step2: 为登录用户设置权限");
		return buildUserAuthorities(user);
		
	}

	/**
	 * 根据userId获取社交用户信息 静默方式注册的时候 findBySocialUserId userPo getUserId socialUserId
	 * 非静默方式注册的时候findByUsername userPo getUserId username
	 */
	@Override
	public SocialUserDetails loadUserByUserId(String userId) throws UsernameNotFoundException {
		logger.info("社交登录用户ID:" + userId);
		Optional<StaffPo> option = userRepository.findById(Integer.valueOf(userId));
		if (!option.isPresent()) {
			throw new UsernameNotFoundException("用户不存在!");
		}
		return buildUserAuthorities(option.get());
	}

	/**
	 * 创建用户，并给用户分配角色
	 */
	private SocialUserDetails buildUserAuthorities(StaffPo po) {
		Map<String, GrantedAuthority> urlMap = Maps.newHashMap();
		// 将权限url信息加入到urls
		List<RolePo> roles = po.getRoles();
		if (roles != null) {
			for (RolePo role : roles) {
				List<PermPo> permissions = role.getPerms();
				for (PermPo permissionPo : permissions) {
					String url = permissionPo.getUrl();
					if (StringUtils.isEmpty(url)) {
						continue;
					}
					url = url.trim();
					urlMap.put(url, new SimpleGrantedAuthority(url));
				}
			}
		}
		
		StaffDto dto = new StaffDto();
		try {
			JPAUtil.fatherToChild(po, dto);
		} catch (Exception e) {
		}
		
		dto.getUrlMap().putAll(urlMap);
		return dto;
	}
}
